﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class LevelManager : MonoSingleton<LevelManager>
{
    public string NextSceneName = "Title2";

    //[SerializeField]
    public EnemyInfo[] enemyArray;

    public List<GameObject> enemies;

    public GameObject enemyPrefabDash;
    public GameObject enemyPrefabSavezone;
    public GameObject enemyPrefabCircle;
    public GameObject maskBG;

    public PlayerOne player1;
    public PlayerTwo player2;

    public int enemyIndex = 0;
    public int enemyTotal;
    public int enemyKilled;

    public float lastSpawnTimeStamp;
    private bool bSceneComplete;

    private void Start()
    {
        lastSpawnTimeStamp = Time.time;
        enemyTotal = enemyArray.Length;

        GameObject player1Obj = GameObject.Find("Player1");
        if (player1Obj)
        {
            player1 = player1Obj.GetComponent<PlayerOne>();
        }
        GameObject player2Obj = GameObject.Find("Player2");
        if (player2Obj)
        {
            player2 = player2Obj.GetComponent<PlayerTwo>();
        }
    }

    private void OnEnable()
    {
        EventMgr.Register(Events.ON_ENEMY_KILLED, OnEnemyKilled);
        EventMgr.Register(Events.ON_PLAYER1_DIE, OnPlayer1Die);
        EventMgr.Register(Events.ON_PLAYER2_DIE, OnPlayer2Die);
    }

    private void OnDisable()
    {
        EventMgr.UnRegister(Events.ON_ENEMY_KILLED, OnEnemyKilled);
        EventMgr.UnRegister(Events.ON_PLAYER1_DIE, OnPlayer1Die);
        EventMgr.UnRegister(Events.ON_PLAYER2_DIE, OnPlayer2Die);
    }

    void Update()
    {
        if (enemyIndex >= enemyTotal)
        {
            return;
        }

        if (Time.time >= lastSpawnTimeStamp + enemyArray[enemyIndex].interval)
        {
            //初始位置
            float levelDownEdge = EnumBase.levelDownEdge;
            float levelTopEdge = EnumBase.levelTopEdge;
            string sceneName = SceneManager.GetActiveScene().name;
            if (sceneName == "FinalLevel1")
            {
                levelTopEdge = 2.5f;
                levelDownEdge = -2.5f;
            }

            float spawnX;
            float spawnY = Random.Range(levelDownEdge, levelTopEdge);
            FaceDir dir;
            GameObject enemy;

            switch (enemyArray[enemyIndex].mode)
            {
                case EnemyMode.ENEMY_MODE_DASH_FROM_LEFT:
                    spawnX = EnumBase.spawnLeftEdge;
                    dir = FaceDir.FACE_DIR_RIGHT;
                    break;
                case EnemyMode.ENEMY_MODE_DASH_FROM_RIGHT:
                    spawnX = EnumBase.spawnRightEdge;
                    dir = FaceDir.FACE_DIR_LEFT; 
                    break;
                case EnemyMode.ENEMY_MODE_SAVEZONE_LEFT:
                    spawnX = EnumBase.spawnLeftEdge;
                    dir = FaceDir.FACE_DIR_RIGHT;
                    break;
                case EnemyMode.ENEMY_MODE_SAVEZONE_RIGHT:
                    spawnX = EnumBase.spawnRightEdge;
                    dir = FaceDir.FACE_DIR_LEFT; 
                    break;
                case EnemyMode.ENEMY_MODE_CIRCLE_FROM_LEFT:
                    spawnX = -10.0f;
                    if (Random.Range(0,2) == 0) spawnY = EnumBase.playerMaxY;
                    else spawnY = EnumBase.playerMinY;

                    dir = FaceDir.FACE_DIR_RIGHT;
                    break;
                case EnemyMode.ENEMY_MODE_CIRCLE_FROM_RIGHT:
                    spawnX = 10.0f;
                    if (Random.Range(0,2) == 0) spawnY = EnumBase.playerMaxY;
                    else spawnY = EnumBase.playerMinY;

                    dir = FaceDir.FACE_DIR_LEFT; 
                    break;
                default:
                    return;
            }

            Vector3 spawnPos = new Vector3(spawnX, spawnY, 0f);
            if (enemyArray[enemyIndex].mode == EnemyMode.ENEMY_MODE_DASH_FROM_LEFT || enemyArray[enemyIndex].mode == EnemyMode.ENEMY_MODE_DASH_FROM_RIGHT)
            {
                enemy = GameObject.Instantiate(enemyPrefabDash, spawnPos, Quaternion.identity);
            }
            else if (enemyArray[enemyIndex].mode == EnemyMode.ENEMY_MODE_SAVEZONE_LEFT || enemyArray[enemyIndex].mode == EnemyMode.ENEMY_MODE_SAVEZONE_RIGHT)
            {
                enemy = GameObject.Instantiate(enemyPrefabSavezone, spawnPos, Quaternion.identity);
            }
            else if (enemyArray[enemyIndex].mode == EnemyMode.ENEMY_MODE_CIRCLE_FROM_LEFT || enemyArray[enemyIndex].mode == EnemyMode.ENEMY_MODE_CIRCLE_FROM_RIGHT)
            {
                enemy = GameObject.Instantiate(enemyPrefabCircle, spawnPos, Quaternion.identity);
            }
            else
            {
                return;
            }

            enemies.Add(enemy);
            enemy.GetComponent<EnemyBase>().Init(enemyArray[enemyIndex].mode, spawnPos, dir);

            lastSpawnTimeStamp = Time.time;
            enemyIndex++;
        }
    }

    void OnEnemyKilled(object arg1, System.EventArgs arg2)
    {
        GameObject enemy = (GameObject)arg1;
        enemies.Remove(enemy);
        enemyKilled++;
        if (enemyKilled >= enemyTotal && !bSceneComplete)
        {
            bSceneComplete = true;
            Invoke("LevelComplete", 3f);
        }
    }

    void OnPlayer1Die(object arg1, System.EventArgs arg2)
    {
        maskBG.GetComponent<Animator>().SetTrigger("TurnBlack");
        Invoke("ReloadScene", 2f);
    }

    void OnPlayer2Die(object arg1, System.EventArgs arg2)
    {
        maskBG.GetComponent<Animator>().SetTrigger("TurnBlack");
        Invoke("ReloadScene", 2f);
    }

    void ReloadScene()
    {
        EventMgr.ClearAll();
        string sceneName = SceneManager.GetActiveScene().name;
        SceneManager.LoadScene(sceneName);
    }

    public void LevelComplete()
    {
        EventMgr.ClearAll();
        SceneManager.LoadScene(NextSceneName);
    }
}

[System.Serializable]
public struct EnemyInfo
{
    public EnemyMode mode;
    public float interval;
}
